home *** CD-ROM | disk | FTP | other *** search
-
- /* Header file for the SoundTrack interpreting routines: */
-
- /* Copyright © 1991-93 by Frank Seide, Koolbarg 39d, D-22117 Hamburg */
-
- #ifndef __SOUNDTRACKER__
- #define __SOUNDTRACKER__
-
- /***** Constants: *****/
-
- #define RESTYPE_SOUNDTRACK 'STrR'
- #define CHUNK_SIFF 'SIFF' /* FORM SIFF */
-
- /***** Specification of the SoundTracker ('.MOD') format: *****/
-
- #define MAXPTRS 128 /* Size of pointer table */
- #define MAXPTRNS MAXPTRS /* max. number of patterns */
- #define AMIGAVOICES 4
- #define STDPATLENGTH 64
- /* #define AMIGA_PTRNSIZE (STDPATLENGTH * AMIGAVOICES * sizeof (struct AmigaCommand)) */
-
- /* FileInstrData: Instrument descriptor (at the beginning of the file) */
-
- #define MOD_INSTNAME_LEN 22
-
- struct FileInstrData {
- char filename[MOD_INSTNAME_LEN]; /* Original Amiga filename of this imstrument */
- unsigned int numWords; /* Sample length in words (!) (as used for file parsing) */
- int unused : 4; /* (unused, set to zero) */
- int fineTune : 4; /* Finetune value (-8…+7 in 16th of a semi tone) */
- unsigned int volume : 8; /* Initial volume (0…64) */
- unsigned int loopWord; /* Loopstart (in words!) (< 32768), 0 => not looping */
- unsigned int loopWords; /* Looplength (in words!) (loopWord+loopWords < 65536) */
- /* loopWord = 0 => loopWords is the real sample */
- /* length as used by the playing routine. Use */
- /* numWords for parsing the file only! */
- };
-
- /* AmigaCommand: one '.MOD' file command. Patterns are composed of such commands. */
-
- typedef struct AmigaCommand {
- unsigned int InstrHiNibble : 4; /* Number of instrument (hi nibble) */
- unsigned int AmigaPeriod : 12; /* Output frequency = 3.579545 MHz / AmigaPeriod */
- unsigned int InstrLoNibble : 4; /* Number of inst. (lo nibble), 0 => no change */
- unsigned int EffectCmd : 4; /* Effects: Command */
- unsigned int EffectArg : 8; /* and operand */
- } AmigaCommand, *AmigaCommandPtr;
-
- /* How the commands are interpreted: */
- /* (…to be translated) */
-
- /*
- * (1) Vorab:
- * (a) Die folgende Routine wird i. a. alle 20 ms (50 Hz) durchgeführt,
- * beim Amiga ursprünglich im VBL-Interrupt (Name wird hier verwendet).
- * Kann durch STCMD_ADJUST_SPEED feinjustiert werden (9.8ms bis 78 ms).
- * (b) Sie wird für jede Stimme unabhängig durchgeführt, daher wird im folgenden
- * nur eine Stimme betrachtet.
- * (2) Alle 20 ms:
- * (a) Die Aufruf-Frequenz wird zunächst geteilt durch ws_divisor.
- * Der Wert von ws_divisor wird durch STCMD_SET_SPEED gesetzt, Default ist 6.
- * (b) Alle ws_divisor wird ein NEUES Kommando geholt, gespeichert für (c)
- * und gemäß (3) interpretiert.
- * Hier wird das InstrLo/HiNibble und AmigaPeriod ausgewertet,
- * sowie der unmittelbare Effekt (EffectCmd) (nur manche Effekte werden
- * unmittelbar ausgeführt).
- * (c) In allen anderen Aufrufen wird das in (b) gespeicherte EffectCmd
- * interpretiert (4) (periodischer Effekt).
- * Der Effekt könnte auch von (b) unmittelbar interpretiert worden sein.
- * Mit Ausnahme von STCMD_EXTRA wurde dabei jedoch eine andere Routine
- * verwendet, z. B. eine zur Übernahme von Parametern für den periodischen
- * Effekt.
- * (3) Ausführung eines NEUEN Kommandos:
- * Wird nur alle ws_divisor 20 ms-Schritte aufgerufen.
- * (a) Wenn Instrument > 0, dann Instrumentwechsel.
- * Es wird nur der Inhalt des zugehörigen InstrumentRecords in den VoiceRecord
- * kopiert, eine Übergabe an die Abspielroutine findet hier NICHT statt.
- * Dies passiert NUR bei (b).
- * Das Kopieren ist überflüssig, nötig sind nur
- * (a1) ein Instrumenten-Index, (a2) Volume / Finetune und (a3) ein Offset-Wert,
- * der zunächst auf 0 zu setzen ist (für STCMD_SAMPLE_OFFSET).
- * (b) Wenn AmigaPeriod > 0, dann übernehmen in masterPeriod und effectivePeriod.
- * (Ausnahme: wenn EffectCmd = STCMD_PORTAMENTO_TO oder
- * STCMD_PORT_TO_VOL_SLIDE. Dann wird auch der Ton nicht neu angeschlagen).
- * Übernehmen bedeutet, daß der Wert zum nächsten Norm-Ton
- * gerundet wird (anhand einer Tabelle).
- * Mit Hilfe des Fine-Tune-Wertes wird der Norm-Ton dann modifiziert.
- * masterPeriod ist im Normalfall identisch mit dem für die Ausgabe
- * verwendeten Wert, Ausnahmen sind Effekte wie Vibrato oder Arpeggio.
- * masterPeriod wird durch die Portamento-Effekte verändert.
- * Es wird NICHT verändert durch Effekte wie Vibrato oder Arpeggio. Die
- * verwenden masterPeriod als Ausgangspunkt für ihren Effekt.
- * Nach der Übernahme wird der Ton neu angeschlagen, d. h.
- * HIER werden die Sample-Pointer aus den VoiceRecords (evtl. durch (a) gesetzt)
- * an die Abspielroutine übergeben.
- * Eigentlich können die Sample-Pointer hier direkt aus den InstrumentRecords
- * entnommen werden, sofern der Sample-Offset (STCMD_SAMPLE_OFFSET)
- * separat gespeichert hier mit eingerechnet wird.
- * (c) Ausführung unmittelbarer Effekte durch Aufruf entsprechender Routine.
- * Bei STCMD_EXTRA ist die identisch mit der für den periodischen Effekt.
- * (4) Ausführung des periodischen Effekts:
- * Wird in jeden 20 ms-Schritt aufgerufen mit Ausnahme jeden ws_divisor-ten.
- * (a) Der Effekt wird durch Aufruf der entsprechenden Routine ausgeführt.
- * Bei STCMD_EXTRA ist die identisch mit der für den unmittelbaren Effekt.
- */
-
- /* Available effect commands: */
-
- #define STCMD_ARPEGGIO 0
- #define STCMD_PORTAMENTO_UP 1
- #define STCMD_PORTAMENTO_DOWN 2
- #define STCMD_PORTAMENTO_TO 3 /* Portamento with specified destination */
- /* The destination note is specified in AmigaPeriod. When the command */
- /* contains this effect, the note is NOT played again from start, as it would */
- /* usually be for all other effects when AmigaPeriod is > 0. */
- #define STCMD_VIBRATO 4
- #define STCMD_PORT_TO_VOL_SLIDE 5 /* Portamento with destination */
- #define STCMD_VIBRATO_VOL_SLIDE 6
- #define STCMD_TREMOLO 7
- #define STCMD_UNUSED 8 /* ("KarPlusStrong" = TP [0.5 0.5] on samples) */
- #define STCMD_SAMPLE_OFFSET 9 /* Start current inst. sample at offset > 0 */
- /* The starting point of the instrument sample to be used is specified as */
- /* multiples of 256, the offset will be set to (256 * effectArg). */
- /* Achtung: im ProTracker wird der Startpunkt bei jedem Aufruf ERHÖHT, */
- /* was jedoch z. B. bei SPACE DEBRIS dazu führt, daß ein Instrument fast */
- /* nicht mehr zu hören ist. Ein absolutes Setzen klingt so, als ob es so sein soll. */
- #define STCMD_VOLUME_SLIDE 10
- #define STCMD_POSITION_JUMP 11 /* Go to new song position, pattern from start */
- #define STCMD_VOLUME_CHANGE 12 /* Set volume (effectArg 0…64) */
- #define STCMD_PATTERN_BREAK 13 /* Immediately end pattern, start next */
- #define STCMD_EXTRA 14 /* Extra commands */
- /* Hi nibble of effectArg is code of extra command (EXTRA_xxx, see below) */
- #define STCMD_SET_SPEED 15 /* Set 50 Hz divisor (effectArg = 0…31) */
- /* A SoundTracker pattern line is interpreted all (effectArg) VBL interrupts. */
- /* Default value is 6, resulting in 8.3 Hz resolution */
- #define STCMD_ADJUST_SPEED 15 /* Fine tuning of VBL irq freq. (effectArg = 32…255) */
- /* New VBL irq period = 20 ms *125 /EffectArg (Default is 125 => 20 ms, 50 Hz) */
-
- #define EXTRA_FILTER 0 /* Switch Amiga sound filter on/off (obsolete) */
- #define EXTRA_FINE_PORT_UP 1
- #define EXTRA_FINE_PORT_DOWN 2
- #define EXTRA_GLISS_CONTROL 3
- #define EXTRA_VIBRATO_CONTROL 4
- #define EXTRA_FINE_TUNE 5
- #define EXTRA_LOOP 6
- #define EXTRA_TREMOLO_CONTROL 7
- #define EXTRA_UNUSED 8
- #define EXTRA_RETRIGGER_NOTE 9
- #define EXTRA_VOLUME_UP 10
- #define EXTRA_VOLUME_DOWN 11
- #define EXTRA_NOTE_CUT 12
- #define EXTRA_NOTE_DELAY 13
- #define EXTRA_PATTERN_DELAY 14
- #define EXTRA_UNUSED2 15
-
- /* AmigaPattern: structure of one pattern in the '.MOD' file */
-
- typedef struct AmigaPattern {
- AmigaCommand commands[STDPATLENGTH][AMIGAVOICES]; /* 1024 bytes */
- } AmigaPattern;
-
- /* The file format itself (don't use this structure, for documentation only) */
-
- struct SoundTrackSpec {
- char NameSignature[20]; /* Song name (may be different from file name) */
- #define OFFSETINSTR 20 /* Instrument descriptors starting here */
- struct FileInstrData fid[31]; /* Inst. descriptors (31 or 15) */
- Byte numPointers; /* 0x3b6 / 0x1d6: number of pointers USED */
- Byte maxPointers; /* 0x3b7 / 0x1d7; this value is of no value */
- Byte oPointers[MAXPTRS]; /* 0x3b8 / 0x1d8: pointer list (always 128 bytes) */
- long longFmtSignature; /* 0x438 / - : 31 inst. signature ('M.K.' or 'FLT4') */
- struct AmigaPattern patterns[]; /* 0x43c / 0x258: the patterns follow here */
- /* Sample0[]; /* Sample data begin after last pattern */
- };
-
- /***** Macintosh extended '.MOD' format (proprietary): *****/
-
- /* Warning: the format specification has not yet been finished and may change. */
-
- /* CommandRecord: command record used by V2.0 patterns */
-
- typedef struct CommandRecord {
- /* long actionLong; /* $00: 0 => Command is NOP */
- int instrument; /* $00: > 0 => set new instrument */
- Byte noteCmd; /* $02: > 0 => set new note (contains NOTE_xxx) */
- Byte effectCmd; /* $03: > 0 => apply effect (contains EFF_xxx) */
- Byte noteValue; /* $04: Note value for NOTE_xxx (as MIDI value) */
- Byte effectArg; /* $05: Argument value for effectCmd */
- unsigned int extraArg; /* $06: Extra argument (currently unused) */
- } CommandRecord, *CommandPtr;
-
- #define cmd_actionLong 0
- #define cmd_instrument 0
- #define cmd_noteCmd 2
- #define cmd_effectCmd 3
- #define cmd_noteValue 4
- #define cmd_effectArg 5
- #define cmd_extraArg 6
- #define cmd_SIZEOF 8
-
- enum {
- NOTE_IDLE, /* Don't change the note (0) */
- NOTE_ON, /* Note on (additionally) */
- NOTE_OFF, /* Switch additional note off */
- NOTE_SET, /* Release previous, attack new note */
- NOTE_HARD_SET, /* Switch off previous, attack new note ('.MOD') */
- NOTE_PORTAMENTO_TO, /* Special for EFF_PORTAMENTO_TO */
- NOTE_LAST
- };
-
- #define MIDI_FIRST_ST 48 /* First MIDI note used in '.MOD' files */
- #define MIDI_LAST_ST 83 /* Laest MIDI note used in '.MOD' files */
- #define MIDI_NUM 128 /* Number of MIDI notes (including 0 as a dummy) */
-
- /* …to be translated: */
-
- /* Besser: zwei Gruppen von Kommandos */
- /* (1) STYLE_ => Stil des Anschlags der Noten (Portamento, Arpeggio etc.) */
- /* (2) CONTROL_ => Lautstärke, Stereo, Pattern-Break etc. */
-
- enum {
- EFF_IDLE, /* Nix tun (0) */
- EFF_ARPEGGIO,
- EFF_ARPEGGIO_SYM,
- EFF_ARPEGGIO_SYM2,
- EFF_PORTAMENTO_UP,
- EFF_PORTAMENTO_DOWN,
- EFF_PORTAMENTO_TO, /* Accompanied by NOTE_PORTAMENTO_TO */
- EFF_VIBRATO, /* Lo-Nibble: Amplitude, Hi-Nibble: Frequenz */
- EFF_PORT_TO_VOL_SLIDE, /* Portamento mit Zielangabe */
- EFF_VIBRATO_VOL_SLIDE,
- EFF_TREMOLO,
- EFF_SAMPLE_OFFSET, /* Aktuelles Instrument nicht am Beginn starten */
- EFF_VOLUME_STEP, /* Einen Schritt in der Lautstärke */
- EFF_VOLUME_SLIDE, /* Pro VBL einen Schritt in der Lautstärke */
- EFF_NOTE_STEP, /* Einen Schritt in der Note (hoch oder runter) */
- EFF_NOTE_SLIDE, /* Pro VBL einen solchen Schritt */
- EFF_POSITION_JUMP, /* neue Song-Position, Pattern von vorne */
- EFF_VOLUME_CHANGE, /* (Argument 0..64) */
- EFF_STEREO_CHANGE, /* (Argument 128..255) */
- EFF_PATTERN_BREAK, /* Pattern beenden */
- EFF_SET_VBL_DIVISOR, /* (Argument 0..31) */
- EFF_SET_VBL_ADJUST, /* (Argument 32..255) */
- EFF_FINE_PORT_UP,
- EFF_FINE_PORT_DOWN,
- EFF_GLISS_TYPE,
- EFF_VIBRATO_TYPE, /* Vibrato-Typ VIBRATO_TYPE_SINE oder _RAMP */
- EFF_FINE_TUNE,
- EFF_FOR,
- EFF_NEXT,
- EFF_TREMOLO_TYPE,
- EFF_RETRIGGER_NOTE,
- EFF_NOTE_CUT,
- EFF_NOTE_DELAY,
- EFF_DELAY, /* Um effectArg Noten verzögern */
- EFF_END, /* Ende des Stückes */
- EFF_LAST
- };
-
- /* EFF_VIBRATO_TYPE: wie wird Periode bei Vibrato moduliert ? */
- #define VIBRATO_TYPE_SINE 0 /* Sinus */
- #define VIBRATO_TYPE_RAMP_DOWN 1 /* steigende Rampe (-1…+1) (falld. für Freq.) */
- #define VIBRATO_TYPE_RAMP_UP 4 /* fallende Rampe (+1…-1) (Rampen ungerade) */
- #define VIBRATO_TYPE_RECT 2 /* Rechteck (+1, -1) */
- #define VIBRATO_TYPE_RECT2 3 /* (Mehrdeutigkeit im ProTr.: auch Rechteck) */
- #define VIBRATO_TYPE_TRI 5 /* symmetrisches Dreieck */
- #define VIBRATO_KEEP_PHASE 0x80 /* Bei Anschlag Phase NICHT zurücksetzen! */
-
- /***** Data structures for internal representation of song file: *****/
-
- #define POSITION_LEFT 0
- #define POSITION_CENTER 32
- #define POSITION_RIGHT 64
- #define POSITION_SURROUND 96
- #define POSITION_DEFAULT 0xff
- #define POSITION_NO_CHANGE 0xfe
-
- #define VOLUME_DEFAULT 0xff
- #define VOLUME_NO_CHANGE 0xfe
-
- /* Constants for values that may be stored in the speed field: */
- /* Warning: the SoundTracker playing mechanism represents a finite state machine. */
- /* The execution of finite state machines can not be reversed in any cases, so */
- /* playing a song backwards may result in wrong settings of VBLDivisor, */
- /* VBLAdjust and playingTime. Furthermore, jumps in the song can not be reversed. */
- #define SPEED_NORMAL 1 /* Normal playing speed */
- #define SPEED_HOLD 0 /* Hold the music (different from pause) */
- #define SPEED_BACKWARDS -1 /* May not work in any cases! */
- #define SPEED_FASTFORWARD 2 /* Fast forward: values > 1 */
- #define SPEED_FASTERFORWARD 4
- #define SPEED_EVENFASTERFORWARD 8
- #define SPEED_REWIND -2 /* Rewind: values < -1 */
- #define SPEED_FASTERREWIND -4
- #define SPEED_EVENFASTERREWIND -8
-
- /* Workspace: variables used when playing back a song */
-
- typedef struct Workspace {
- signed char speed; /* $00: Soviele Ticks aufeinmal (Spulen; 1 = normal) */
- Byte ffCounter; /* $01: Zähler dafür */
-
- unsigned int VBLFrames; /* $02: soviele Bytes pro VBL-Tick */
- Byte VBLDivisor; /* $04: VBL-Teiler, Default = 6 */
-
- Byte songPos; /* $05: Byte ? */
- int pattPos; /* $06: aktuelle Pattern-Position (Zeilenindex) */
-
- Byte cycle; /* $08: "VBL"-Zähler */
-
- Boolean pattBreak; /* $09: Break-Flag für Patterns */
-
- Boolean loopDetect; /* $0a: Loop-Erkennung ? */
- Boolean looping; /* $0b: Loop wurde erkannt */
-
- Boolean endOfSong; /* $0c: Ende des Stückes (keine neuen Noten mehr) */
- Boolean nextOne; /* $0d: Ende oder Loop; nächstes Stück nehmen */
-
- int speedFactor; /* $0e: Externer Faktor vom User-Interface (in %) */
- unsigned int VBLAdjust; /* $10: ProTrkr. 2.0-VBL-Adjust 32/125 … 255/155 ≈ 0.256 … 2.04 */
- /* VBLAdjust = BPM für VBLDivisor = 6 !! */
-
- int overwriteVoice; /* $12: Echtzeit-Overwrite dieses Kanals */
- CommandRecord overwriteCommand; /* $14: Overwrite dieses Kommandos (0 = inaktiv) */
-
- Fixed playingTime; /* $1c: Spielzeit in Sekunden */
-
- Fixed prevHardFreq; /* $20: auf dieser hardFreq basieren aktuelle Rates */
-
- int ** periodTable; /* $24: Handle auf Amiga-Perioden der MIDI-Töne */
- Byte delay; /* $28: Delay-Counter */
- Byte patternStart; /* $29: EFF_PATTERN_BREAK mit Pos. > 0 */
-
- Byte reserved2[16] ; /* $2a */
-
- int numVoices; /* $3a: Anzahl Stimmen (Anzahl Voice-Records) */
- Handle voices; /* $3c: Handle auf Voice-Records */
-
- Boolean hold; /* $40: Sample nicht updaten (internes Flag) */
- Byte prevSongPos; /* $41: vorige Song-Position */
- int prevPattPos; /* $42: vorige Pattern-Position */
-
- Fixed requestedPlayingTime; /* $44: Jump to value stored here (WO) */
-
- Byte reserved[0x8c]; /* $48 */
- } WorkspaceRecord, *WorkspacePtr;
-
- #define ws_speed 0x00
- #define ws_ffCounter 0x01
- #define ws_VBLFrames 0x02
- #define ws_VBLDivisor 0x04
- #define ws_songPos 0x05
- #define ws_pattPos 0x06
- #define ws_cycle 0x08
- #define ws_pattBreak 0x09
- #define ws_loopDetect 0x0a
- #define ws_looping 0x0b
- #define ws_endOfSong 0x0c
- #define ws_nextOne 0x0d
- #define ws_speedFactor 0x0e
- #define ws_VBLAdjust 0x10
- #define ws_overwriteVoice 0x12
- #define ws_overwriteCommand 0x14
- #define ws_playingTime 0x1c
- #define ws_prevHardFreq 0x20
- #define ws_periodTable 0x24
- #define ws_delay 0x28
- #define ws_patternStart 0x29
- #define ws_numVoices 0x3a
- #define ws_voices 0x3c
- #define ws_hold 0x40
- #define ws_prevSongPos 0x41
- #define ws_prevPattPos 0x42
- #define ws_requestedPlayingTime 0x44
- #define ws_reserved 0x48
- #define ws_SIZEOF 0xd4
-
- /* InstrumentRecord: internal representation of an instrument */
-
- typedef struct InstrumentRecord { /* Don't use, will change */
- /* …später: Instrument-Sharing (sinnvoll, da Instrumente viel Platz brauchen) */
- /* int numRefs; /* $xx: so oft wird dieses Instrument verwendet */
- /* int locks; /* $xx: so oft gelockt (nur HUnlock, wenn locks = 0) */
-
- /* …ganze Ranges angeben! Z.B. Array */
- /* Byte note; /* $xx: dieser Ton ist gespeichert (MIDI-Angabe) */
- /* Fixed sampleFreq; /* $xx: Original-Samplefrequenz */
-
- Handle sample; /* $00: Zeiger auf 1. Sample …wird Offset in dieses Handle */
-
- /* Die folgenden Angaben enthalten 2^ldOverSampling als Faktor: */
- unsigned long length; /* $04: Offset hinter letztes Originalsample */
- unsigned long loopStart; /* $08: hier beginnt Loop (z.Zt. length-loopLength) */
- unsigned long loopLength; /* $0c: Distanz vom Ende zum Loop-Beginn */
-
- /* Zusatzinfo: */
- Byte initialVolume; /* $10: Default-Lautstärke 0…64 (Übern. bei Inst.-Wechsel) */
- Byte instrumentStPos; /* $11: Stereo-Position (Default des Instruments) */
- Byte ldOverSampling; /* $12: Wieoft Frequenz shiften (0..3) ? */
- Byte initialFineTune; /* $13: Frequenzjustage */
- Byte reserved[28];
-
- /* Name: */
- Str63 name; /* $30: Name des Instruments */
- } InstrumentRecord, *InstrumentPtr;
-
- #define ins_sample 0x00
- #define ins_length 0x04
- #define ins_loopStart 0x08
- #define ins_loopLength 0x0c
- #define ins_initialVolume 0x10
- #define ins_instrumentStPos 0x11
- #define ins_ldOverSampling 0x12
- #define ins_initialFineTune 0x13
- #define ins_name 0x30
- #define ins_SIZEOF 0x70
-
- /* TimeTrackRecord: extra track for timing information (currently not used) */
-
- typedef struct TimeTrackRecord { /* Specifies duration of pattern line */
- unsigned int stepNumer; /* $00: Numerator (0 => next line immediately) */
- unsigned int stepDenom; /* $02: Denominator */
- } TimeTrackRecord, * TimeTrackPtr, ** TimeTrackHandle;
-
- #define tt_stepNumer 0
- #define tt_stepDenom 2
- #define tt_SIZEOF 4
-
- /* PatternRecord: a pattern in memory */
-
- #define MAXTRACKS 32
-
- typedef struct PatternRecord {
- unsigned int commandsOffset; /* $00: offset to commands */
- int res1; /* $02 */
-
- /* References: */
- unsigned int songRefs; /* $04: How often used in song ? */
- unsigned int spareRefs; /* $06: How often used in spare ? */
- unsigned int undoRefs; /* $08: How often used in undo buffer ? */
- unsigned int clipBoardRefs; /* $0a: How often used in clipboard ? */
- long res2; /* $0c */
-
- /* Pattern dimensions: can be changed with ReshapePattern() */
- /* (actually, ReshapePattern() never decreases any dimension) */
- unsigned int numTracks; /* $10: number of active tracks */
- unsigned int length; /* $12: number of active lines */
- unsigned int width; /* $14: width of array (≥ numVoices) */
- unsigned int height; /* $16: height of array (≥ length) */
- unsigned int rowBytes; /* $18: length of line in bytes (for player) */
- Byte res3[6]; /* $1a */
-
- /* More info: */
- Str255 name; /* $20: Pattern name */
- Byte localKey; /* $120: key (-1: use globalKey) */
- Byte res4; /* $121 */
- Byte patternDefStPos[MAXTRACKS]; /* $122: Default stereo positions */
- int res5; /* $142 */
-
- /* Time-Track: */
- TimeTrackHandle timeTrack; /* $144 */
-
- /* Contents of pattern: */
- /* Warning: always access via commandOffset (see above), so more fields */
- /* can be inserted in PatternRecord! */
- CommandRecord commands[]; /* $148: Command array */
- } PatternRecord, *PatternPtr, **PatternHandle;
-
- typedef PatternHandle ** PatternListHandle; /* Handle to array of PatternHandles */
-
- #define pat_commandsOffset 0x00
- #define pat_songRefs 0x04
- #define pat_spareRefs 0x06
- #define pat_undoRefs 0x08
- #define pat_clipBoardRefs 0x0a
- #define pat_numTracks 0x10
- #define pat_length 0x12
- #define pat_width 0x14
- #define pat_height 0x16
- #define pat_rowBytes 0x18
- #define pat_name 0x20
- #define pat_localKey 0x120
- #define pat_patternDefStPos 0x122
- #define pat_timeTrack 0x144
- #define pat_commands 0x148
- #define pat_SIZEOF 0x148
-
- /* SoundTrack: main data structure and handle to song in memory */
-
- /* Commented fields may be accessed directly. However, to access the workspace */
- /* and instruments, use corresponding routines to obtain a pointer. This allows */
- /* changes in the data structure. */
-
- /* This record cannot be shared, a SoundTrack can only be played once at a time! */
-
- typedef struct SoundTrack {
- struct PChannel * pchannel; /* $00: Linked PChannel (NULL => none) */
- char signature[21]; /* $04: Original '.MOD' song name */
- Byte ldOverSampling; /* $19: Apply anti-alias filter at load time (RO) */
- Boolean check; /* $1a: Is result of structure check, don't play! */
- Byte paddedInstruments; /* $1b */
- WorkspaceRecord workspace; /* $1c: Workspace (use routine to get address!) */
-
- Byte numInstruments; /* $f0: Number of instruments */
- Byte pad1a; /* $f1 */
- Byte pad1b; /* $f2 */
-
- /* Pointer list: */
- Byte numPointers; /* $f3: Number of pointers USED (-> song length) */
- Handle pointers; /* $f4: Handle to pattern references */
-
- /* Reference Count: */
- int refCount; /* $f8: Freigabe nur bei refCount = 1 */
-
- /* Patterns: */
- int numPatterns; /* $fa: Number of patterns */
- PatternListHandle patterns; /* $fc: Handle to list of pattern handles */
-
- /* Dateityp ('M.K.', 'PRO ' (mit ProTracker-Eff.), 'FLT4/8', 'OLD ' (15 Stimmen), 'OKTA'): */
- OSType typeID; /* $100: Dateityp */
-
- long paddedBytes; /* $104 */
- Byte filler[12];
-
- /* Extended song info for editor: */
- Rect windowRect; /* $114: 'rect' of edit window (pos, size) */
- Byte globalKey; /* $11c: 'KEY_' main key of the song (MIDI-like) */
- Byte initialVBLDivisor; /* $11d: 'SSPD' Initial VBL divisor */
- unsigned int initialVBLAdjust; /* $11e: 'SADJ' Initial VBL period */
- Fixed totalPlayingTime; /* $120: 'TTIM' Total playing time in seconds */
- unsigned int beatsPerMinute; /* $104: 'BPM_' (ersatzweise aus Songp. 2 geschätzt) */
- Byte res[10]; /* $126 */
- Str255 title; /* $130: 'NAME' Song title */
- Str255 author; /* $230: 'AUTH' Author (name / address) */
- Str255 arrangeur; /* $330: 'ARRG' Arranger (name / address) */
- Str255 copyright; /* $430: '(c) ' Copyright notice */
- Str255 annotation; /* $530: 'ANNO' Author's annotation */
- Str255 reservedStr; /* $630: …wech */
-
- /* Instruments (do NOT access directly, this WILL change)! */
- InstrumentRecord instruments[]; /* $730: Array of InstrumentRecords */
- } SoundTrack, * SoundTrackPtr, ** SoundTrackHandle;
-
- #define st_pchannel 0x00
- #define st_signature 0x04
- #define st_ldOverSampling 0x19
- #define st_check 0x1a
- #define st_paddedInstruments 0x1b
- #define st_workspace 0x1c
- #define st_numInstruments 0xf0
- #define st_numPointers 0xf3
- #define st_pointers 0xf4
- #define st_refCount 0xf8
- #define st_numPatterns 0xfa
- #define st_patterns 0xfc
- #define st_typeID 0x100
- #define st_paddedBytes 0x104
- #define st_windowRect 0x114
- #define st_globalKey 0x11c
- #define st_initialVBLDivisor 0x11d
- #define st_initialVBLAdjust 0x11e
- #define st_totalPlayingTime 0x120
- #define st_beatsPerMinute 0x124
- #define st_title 0x130
- #define st_author 0x230
- #define st_arrangeur 0x330
- #define st_copyright 0x430
- #define st_annotation 0x530
- #define st_instruments 0x730
-
- /***** Error codes: *****/
-
- #define errBadFormat badMDBErr /* GetSoundTrack(): wrong or unsupp. file format */
-
- /***** Function prototypes: *****/
-
- /*** Reading and writing song files: ***/
- /* Note: writing NOT implemented yet */
-
- extern pascal OSErr GetSoundTrack (int vRefNum, StringPtr fName, Byte ldOverSampling,
- SoundTrackHandle *soundTrackHandle, Boolean check);
- extern pascal OSErr HGetSoundTrack (int vRefNum, long dirID, StringPtr fName, Byte ldOverSampling,
- SoundTrackHandle *soundTrackHandle, Boolean check);
- extern pascal OSErr FSpGetSoundTrack (FSSpecPtr spec, Byte ldOverSampling,
- SoundTrackHandle *soundTrackHandle, Boolean check);
- extern pascal OSErr PutSoundTrack (int vRefNum, StringPtr fName, SoundTrackHandle sth);
- extern pascal OSErr HPutSoundTrack (int vRefNum, long dirID, StringPtr fName, SoundTrackHandle sth);
- extern pascal OSErr FSpPutSoundTrack (FSSpecPtr spec, SoundTrackHandle sth);
-
- /*** Handling song resources: ***/
- /* Note: this enables you reading '.MOD' “files” from resources! */
-
- extern pascal OSErr GetSoundTrackResource (ResType resType, int resID, Byte ldOverSampling,
- SoundTrackHandle *soundTrackHandle, Boolean check);
- extern pascal OSErr GetNamedSoundTrackResource (ResType resType, StringPtr resName,
- Byte ldOverSampling, SoundTrackHandle *soundTrackHandle, Boolean check);
- extern pascal OSErr AddSoundTrackResource (int resType, int resId,
- Boolean extraSndRes, SoundTrackHandle sth);
-
- /*** Memory management: ***/
-
- extern pascal OSErr NewSoundTrack (int numVoices, int numPatterns, int numInstruments,
- SoundTrackHandle *sth);
- extern pascal void DisposeSoundTrack (SoundTrackHandle sth);
- extern pascal OSErr MoreInstruments (SoundTrackHandle sth, int numInstruments);
- extern pascal OSErr MoreVoices (SoundTrackHandle sth, int numVoices);
- extern pascal OSErr MorePatterns (SoundTrackHandle sth, int numPatterns);
- extern pascal OSErr ReshapePattern (SoundTrackHandle sth, int index, int newTracks, int newLength);
-
- /*** Interfacing the playing routines: ***/
-
- extern pascal struct SoundTrack * LockSoundTrack (SoundTrackHandle soundTrack);
- extern pascal void UnlockSoundTrack (SoundTrackHandle soundTrack);
-
- extern pascal void LinkSoundTrack (SoundTrackHandle soundTrack, struct PChannel * pc);
- extern pascal void UnlinkSoundTrack (SoundTrackHandle soundTrack);
- extern pascal void UpdateSoundTrack (SoundTrackHandle soundTrack);
-
- /*** Data structure access: ***/
-
- extern pascal InstrumentPtr GetSoundTrackInstrument (SoundTrackHandle sth, int i);
- extern pascal WorkspacePtr GetSoundTrackWorkspace (SoundTrackHandle sth);
- extern pascal PatternHandle GetSoundTrackPattern (SoundTrackHandle sth, int i);
-
- /*** Other routines: ***/
-
- extern pascal OSErr RecalcSoundTrack (SoundTrackHandle sth);
- extern pascal void SetSoundTrackStereoPosition (SoundTrackHandle sth, int i, Byte pos);
- extern pascal int VersionSoundTrack();
- extern pascal void CopyrightSoundTrack (StringPtr s);
-
- #endif
-